<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>私信聊天</title>
    <style>
        * {
            box-sizing: border-box;
            font-family: 'Segoe UI', Arial, sans-serif;
        }

        body {
            margin: 0;
            padding: 0;
            background-color: #f5f5f5;
            color: #333;
        }

        .chat-container {
            display: flex;
            height: 100vh;
            max-width: 1200px;
            margin: 0 auto;
            background-color: white;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }

        .contacts-sidebar {
            width: 300px;
            border-right: 1px solid #e0e0e0;
            overflow-y: auto;
        }

        .chat-header {
            padding: 15px;
            border-bottom: 1px solid #e0e0e0;
            font-weight: bold;
            background-color: #f9f9f9;
        }

        .contact-list {
            list-style: none;
            padding: 0;
            margin: 0;
        }

        .contact-item {
            padding: 15px;
            border-bottom: 1px solid #e0e0e0;
            cursor: pointer;
            display: flex;
            align-items: center;
            position: relative;
        }

        .contact-item:hover {
            background-color: #f0f0f0;
        }

        .contact-item.active {
            background-color: #e3f2fd;
        }

        .contact-avatar {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            margin-right: 10px;
            background-color: #ddd;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #666;
            font-weight: bold;
        }

        .contact-info {
            flex: 1;
            min-width: 0;
        }

        .contact-name {
            font-weight: bold;
            margin-bottom: 3px;
            display: flex;
            justify-content: space-between;
        }

        .unread-count {
            background-color: #ff4d4f;
            color: white;
            border-radius: 10px;
            padding: 2px 6px;
            font-size: 12px;
        }

        .contact-preview {
            font-size: 13px;
            color: #666;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .chat-main {
            flex: 1;
            display: flex;
            flex-direction: column;
        }

        .chat-messages {
            flex: 1;
            padding: 20px;
            overflow-y: auto;
            background-color: #fafafa;
            display: flex;
            flex-direction: column;
        }

        .message {
            margin-bottom: 15px;
            max-width: 70%;
        }

        .message.received {
            align-self: flex-start;
        }

        .message.sent {
            align-self: flex-end;
        }

        .message-content {
            padding: 10px 15px;
            border-radius: 18px;
            position: relative;
            word-break: break-word;
        }

        .message.received .message-content {
            background-color: white;
            border: 1px solid #e0e0e0;
        }

        .message.sent .message-content {
            background-color: #0084ff;
            color: white;
        }

        .message-time {
            font-size: 11px;
            color: #999;
            margin-top: 5px;
            text-align: right;
        }

        .chat-input {
            padding: 15px;
            border-top: 1px solid #e0e0e0;
            display: flex;
            align-items: center;
            background-color: white;
        }

        .message-input {
            flex: 1;
            padding: 10px 15px;
            border: 1px solid #e0e0e0;
            border-radius: 20px;
            outline: none;
            resize: none;
            height: 40px;
            max-height: 120px;
        }

        .send-button {
            margin-left: 10px;
            padding: 8px 15px;
            background-color: #0084ff;
            color: white;
            border: none;
            border-radius: 20px;
            cursor: pointer;
        }

        .send-button:hover {
            background-color: #0073e6;
        }

        .send-button:disabled {
            background-color: #ccc;
            cursor: not-allowed;
        }

        .no-chat-selected {
            display: flex;
            align-items: center;
            justify-content: center;
            flex: 1;
            color: #999;
            font-size: 18px;
        }

        .loading {
            text-align: center;
            padding: 10px;
            color: #999;
        }
    </style>
</head>
<body>
<div id="app">
    <div class="chat-container">
        <div class="contacts-sidebar">
            <div class="chat-header">私信</div>
            <ul class="contact-list">
                <div v-if="loadingContacts" class="loading">加载中...</div>
                <li v-for="contact in contacts"
                    :key="contact.userId"
                    class="contact-item"
                    :class="{ active: selectedContact?.uid === contact.uid }"
                    @click="selectContact(contact)">
                    <div class="contact-avatar">
                        {{ contact.name.charAt(0) }}
                    </div>
                    <div class="contact-info">
                        <div class="contact-name">
                            {{ contact.name }}
                            <span v-if="contact.unread > 0" class="unread-count">{{ contact.unread }}</span>
                        </div>
                        <div class="contact-preview" :title="contact.lastMessage">
                            {{ contact.lastMessage }}
                        </div>
                    </div>
                </li>
            </ul>
        </div>

        <div class="chat-main">
            <div v-if="!selectedContact" class="no-chat-selected">
                请从左侧选择聊天对象
            </div>
            <template v-else>
                <div class="chat-header">{{ selectedContact.name }}</div>
                <div class="chat-messages" ref="messagesContainer">
                    <div v-for="message in currentMessages"
                         :key="message.mid"
                         class="message"
                         :class="message.sid === currentUserId ? 'sent' : 'received'">
                        <div class="message-content">{{ message.content }}</div>
                        <div class="message-time">{{ formatMessageTime(message.ctime) }}</div>
                    </div>
                </div>
                <div class="chat-input">
                        <textarea
                                v-model="newMessage"
                                @keydown.enter.exact.prevent="sendMessage"
                                placeholder="输入消息..."
                                class="message-input"></textarea>
                    <button
                            @click="sendMessage"
                            class="send-button"
                            :disabled="!newMessage.trim()">发送</button>
                </div>
            </template>
        </div>
    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data() {
            return {
                currentUserId: JSON.parse(localStorage.getItem('userInfo')).uid,
                contacts: [],
                messages: {},
                selectedContact: null,
                newMessage: '',
                loadingContacts: true,
                sending: false,
                messagePollInterval: null
            }
        },
        computed: {
            currentMessages() {
                return this.selectedContact
                    ? this.messages[this.selectedContact.uid] || []
                    : []
            }
        },
        mounted() {
            this.loadContacts();
            this.setupMessagePolling();
            this.setupRealtimeListener(); // 新增
        },
        beforeDestroy() {
            if (this.broadcastChannel) {
                this.broadcastChannel.close();
            }
            clearInterval(this.messagePollInterval)
        },
        methods: {
            setupRealtimeListener() {
                // 监听localStorage变化
                window.addEventListener('storage', (e) => {
                    if (e.key === 'messageUpdateTrigger') {
                        this.handleMessageUpdate();
                    }
                });

                // 初始化广播通道
                this.broadcastChannel = new BroadcastChannel('message_updates');
                this.broadcastChannel.onmessage = (event) => {
                    if (event.data.type === 'new_message' &&
                        event.data.receiverId === this.currentUserId) {
                        this.handleMessageUpdate(event.data.senderId);
                    }
                };
            },

            handleMessageUpdate(senderId = null) {
                // 刷新当前联系人列表
                this.loadContacts();

                // 如果更新的是当前聊天对象
                if (senderId && this.selectedContact?.uid === senderId) {
                    this.loadMessages(senderId);
                    this.scrollToBottom();
                }
            },
            // 加载联系人列表
            async loadContacts() {
                try {
                    // 1. 获取联系人ID列表
                    const contactsRes = await fetch(`/lv-other/message/contacts?userId=${this.currentUserId}`)
                    const contactsData = await contactsRes.json()

                    if (contactsData.code !== 1 || !contactsData.data?.length) {
                        this.loadingContacts = false
                        return
                    }

                    // 2. 批量获取用户信息
                    const usersRes = await fetch(`/lv-user/lvuser/batch-info?uids=${contactsData.data.join(',')}`)
                    const usersData = await usersRes.json()

                    // 3. 获取每个联系人的最后消息和未读数
                    this.contacts = await Promise.all(contactsData.data.map(async uid => {
                        const [historyRes, unreadRes] = await Promise.all([
                            // 修改为获取完整历史记录并排序
                            fetch(`/lv-other/message/history?senderId=${this.currentUserId}&receiverId=${uid}`),
                            fetch(`/lv-other/message/unread/count?userId=${this.currentUserId}&senderId=${uid}`)
                        ])

                        const history = (await historyRes.json()).data || []
                        const unread = (await unreadRes.json()).data || 0

                        // 获取最新的一条消息
                        const lastMsg = history.sort((a, b) => new Date(b.ctime) - new Date(a.ctime))[0] || {}

                        return {
                            uid,
                            name: usersData.data.find(u => u.uid === uid)?.uname || `用户${uid}`,
                            lastMessage: lastMsg.content || '暂无消息',
                            lastMessageTime: lastMsg.ctime || '',
                            unread: unread
                        }
                    }))

                } catch (error) {
                    console.error('加载联系人失败:', error)
                } finally {
                    this.loadingContacts = false
                }
            },

            // 选择联系人
            async selectContact(contact) {
                if (this.selectedContact?.uid === contact.uid) return
                this.selectedContact = contact

                // 加载聊天记录
                if (!this.messages[contact.uid]) {
                    await this.loadMessages(contact.uid)
                }

                // 标记已读
                await this.markMessagesAsRead()
                this.scrollToBottom()
            },

            // 加载历史消息
            async loadMessages(contactId) {
                try {
                    const res = await fetch(
                        `/lv-other/message/history?senderId=${this.currentUserId}&receiverId=${contactId}`
                    )
                    const result = await res.json()

                    if (result.code === 1) {
                        // 修改为升序排序（最早的在前，最新的在后）
                        const sortedMessages = result.data.sort((a, b) =>
                            new Date(a.ctime) - new Date(b.ctime)
                        )
                        // 使用 Vue.set 确保响应式更新
                        this.$set(this.messages, contactId, sortedMessages)
                        this.scrollToBottom()
                    }
                } catch (error) {
                    console.error('消息加载失败:', error)
                }
            },

            // 发送消息
            async sendMessage() {
                const content = this.newMessage.trim()
                if (!content || !this.selectedContact || this.sending) return

                this.sending = true
                try {
                    const res = await fetch('/lv-other/message/send', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({
                            sid: this.currentUserId,
                            rid: this.selectedContact.uid,
                            content: content,
                            read: 0
                        })
                    })

                    const result = await res.json()
                    if (result.code === 1) {
                        // 添加到本地消息列表
                        const newMessage = {
                            mid: result.data,
                            sid: this.currentUserId,
                            rid: this.selectedContact.uid,
                            content: content,
                            ctime: new Date().toISOString(),
                            read: 0
                        }

                        if (!this.messages[this.selectedContact.uid]) {
                            this.$set(this.messages, this.selectedContact.uid, [])
                        }
                        this.messages[this.selectedContact.uid].push(newMessage)

                        // 更新联系人最后消息
                        const contact = this.contacts.find(c => c.uid === this.selectedContact.uid)
                        if (contact) {
                            contact.lastMessage = content
                            contact.unread = 0
                        }

                        this.newMessage = ''
                        this.scrollToBottom()
                    }
                } finally {
                    this.sending = false
                }
            },

            // 实时消息轮询
            setupMessagePolling() {
                this.messagePollInterval = setInterval(async () => {
                    if (!this.selectedContact) return

                    try {
                        const params = new URLSearchParams({
                            after: this.lastPollTime || Date.now() - 300000 // 默认查询5分钟内的消息
                        });

                        const res = await fetch(
                            `/lv-other/message/history?senderId=${this.selectedContact.uid}&receiverId=${this.currentUserId}&${params}`
                        );

                        // 更新最后轮询时间
                        this.lastPollTime = Date.now();

                        if (result.code === 1 && result.data.length > 0) {
                            // 检查新消息是否已经存在
                            const existingIds = new Set(this.currentMessages.map(m => m.mid))
                            const newMessages = result.data.filter(msg => !existingIds.has(msg.mid))

                            if (newMessages.length > 0) {
                                // 合并并排序消息
                                const allMessages = [...newMessages, ...this.currentMessages]
                                    .sort((a, b) => new Date(b.ctime) - new Date(a.ctime))

                                this.$set(this.messages, this.selectedContact.uid, allMessages)
                                this.scrollToBottom()

                                // 更新未读计数
                                const unreadCount = newMessages.filter(
                                    m => m.sid === this.selectedContact.uid && m.read === 0
                                ).length
                                if (unreadCount > 0) {
                                    this.updateUnreadCount(unreadCount)
                                }
                            }
                        }
                    } catch (error) {
                        console.error('消息轮询失败:', error)
                    }
                }, 3000)
            },

            // 更新未读计数
            updateUnreadCount(count) {
                const contact = this.contacts.find(c => c.uid === this.selectedContact.uid)
                if (contact) {
                    contact.unread = (contact.unread || 0) + count
                }
            },

            // 标记消息为已读
            async markMessagesAsRead() {
                if (!this.selectedContact) return;

                try {
                    const unreadMessages = this.currentMessages
                        .filter(m => m.read === 0 && m.sid === this.selectedContact.uid);

                    if (unreadMessages.length > 0) {
                        const messageIds = unreadMessages.map(m => m.mid);
                        const res = await fetch('/lv-other/message/mark-read', {
                            method: 'POST',
                            headers: { 'Content-Type': 'application/json' },
                            body: JSON.stringify(messageIds)
                        });

                        const result = await res.json();
                        if (result.code === 1) {
                            // 更新本地未读状态
                            this.currentMessages.forEach(m => m.read = 1);
                            const contact = this.contacts.find(c => c.uid === this.selectedContact.uid);
                            if (contact) contact.unread = 0;

                            // 确保通知被发送
                            this.notifyHomePageUnreadUpdate();

                            // 强制重新获取未读总数
                            await this.fetchTotalUnreadCount();
                        }
                    }
                } catch (error) {
                    console.error('标记已读失败:', error);
                }
            },

            // 新增方法：获取总未读消息数
            async fetchTotalUnreadCount() {
                try {
                    const res = await fetch(`/lv-other/message/unread/count?userId=${this.currentUserId}`);
                    const result = await res.json();
                    if (result.code === 1) {
                        // 这个调用会触发首页更新
                        this.notifyHomePageUnreadUpdate();
                    }
                } catch (error) {
                    console.error('获取总未读消息数失败:', error);
                }
            },

            // 辅助方法
            scrollToBottom() {
                this.$nextTick(() => {
                    const container = this.$refs.messagesContainer
                    if (container) {
                        container.scrollTop = container.scrollHeight
                    }
                })
            },

            formatMessageTime(dateTimeStr) {
                const date = new Date(dateTimeStr)
                const options = {
                    hour: '2-digit',
                    minute: '2-digit',
                    year: 'numeric',
                    month: 'short',
                    day: 'numeric'
                }

                // 如果是今天只显示时间
                if (new Date().toDateString() === date.toDateString()) {
                    return date.toLocaleTimeString('zh-CN', {
                        hour: '2-digit',
                        minute: '2-digit'
                    })
                }
                return date.toLocaleDateString('zh-CN', options)
            }
        }
    })
</script>
</body>
</html>